// =================================================================================================
//
//	CopyEngine Framework
//	Copyright 2012 Eran. All Rights Reserved.
//
//	This program is free software. You can redistribute and/or modify it
//	in accordance with the terms of the accompanying license agreement.
//
// =================================================================================================

package copyengine.utils.effect.ghostShadow
{
	import com.greensock.TweenMax;

	import starling.display.DisplayObjectContainer;
	import starling.display.Image;
	import starling.textures.Texture;

	/**
	 *实现 残影效果的动画类 <b>注意!! 该类本身并不为显示对象</b>
	 *
	 * @author eran
	 *
	 */
	public final class CEGhostShadowSprite
	{
		private var mSpTexture:Texture;
		private var mFragmentLiftTime:Number;

		private var mParentContainer:DisplayObjectContainer;
		private var mRealBody:Image;
		private var mSubFragmentContainer:DisplayObjectContainer;

		private var mAllLiveSubFragmentVector:Vector.<CEGhostShadowSpriteFragment>;
		private var mAllRecycleSubFragmentVector:Vector.<CEGhostShadowSpriteFragment>;

		private var mCurrentPosX:Number;
		private var mCurrentPosY:Number;

		private var mIsDisposed:Boolean=false;

		public function CEGhostShadowSprite()
		{
		}

		//=================================
		//== Initianlize & Dispose
		//=================================

		/**
		 *	初始化残影Sp
		 *
		 * @param _spTexture							残影的纹理贴图
		 * @param _realBodyParentContainer				残影本体所在的Container(具体原因 @see http://git.oschina.net/eran/CEGhostShadowSprite)
		 * @param _shadowFragmentParentContainer		残影所在的Container(具体原因 @see http://git.oschina.net/eran/CEGhostShadowSprite)
		 * @param _initPosX								残影初始化时候所在的位置X
		 * @param _initPosY								残影初始化时候所在的位置Y
		 * @param _fragmentLiftTime						每个残影消失的时间
		 *
		 */
		public function initialize(_spTexture:Texture, _realBodyParentContainer:DisplayObjectContainer,
								   _shadowFragmentParentContainer:DisplayObjectContainer,
								   _initPosX:Number=0, _initPosY:Number=0,
								   _fragmentLiftTime:Number=1.2):void
		{
			mSpTexture=_spTexture;
			mFragmentLiftTime=_fragmentLiftTime;
			mParentContainer=_realBodyParentContainer;

			//=============
			//==真实的纹理
			mRealBody=new Image(mSpTexture);
			mRealBody.x=_initPosX;
			mRealBody.y=_initPosY;
			mCurrentPosX=_initPosX;
			mCurrentPosY=_initPosY;
			mParentContainer.addChild(mRealBody);

			//===========
			//==残影
			mAllLiveSubFragmentVector=new Vector.<CEGhostShadowSpriteFragment>();
			mAllRecycleSubFragmentVector=new Vector.<CEGhostShadowSpriteFragment>();
			mSubFragmentContainer=_shadowFragmentParentContainer=_shadowFragmentParentContainer;
		}


		public function dispose():void
		{
			if (!mIsDisposed)
			{
				TweenMax.killTweensOf(this);

				mRealBody.removeFromParent(true);
				mRealBody=null;

				while (mAllLiveSubFragmentVector.length > 0)
				{
					mAllLiveSubFragmentVector.pop().dispoise();
				}
				while (mAllRecycleSubFragmentVector.length > 0)
				{
					mAllRecycleSubFragmentVector.pop().dispoise();
				}
				mAllLiveSubFragmentVector=null;
				mAllRecycleSubFragmentVector=null;
				mIsDisposed=true;
			}
		}

		//=================================
		//== Public Function
		//=================================

		public function set x(_value:Number):void  { mRealBody.x=_value; mCurrentPosX=_value; }

		public function get x():Number  { return mCurrentPosX; }

		public function set y(_value:Number):void  { mRealBody.y=_value; mCurrentPosY=_value; }

		public function get y():Number  { return mCurrentPosY; }


		private var mTriggerValue:int=0;

		/**
		 * 该值没有任何实际用途,只是为了方便挂载到TweenLite中,这样既可以直接调用</br>
		 * TweenLite.to(this,1,{magicTriggerValue:this.magicTriggerValue+10})</br>
		 * 这样不用再写TweenLite的onUpdate函数也可以实现残影效果
		 */
		public function get magicTriggerValue():int  { return mTriggerValue; }

		public function set magicTriggerValue(_value:int):void  { mTriggerValue=_value; markSubFragmentToCurrentPosition()}

		public function markSubFragmentToCurrentPosition():void
		{
			var fragment:CEGhostShadowSpriteFragment
			if (mAllRecycleSubFragmentVector.length > 0)
			{
				fragment=mAllRecycleSubFragmentVector.pop();
				fragment.reuse(mCurrentPosX, mCurrentPosY);
			}
			else
			{
				fragment=new CEGhostShadowSpriteFragment();
				fragment.initialize(mSpTexture,
									mSubFragmentContainer,
									mCurrentPosX, mCurrentPosY,
									mFragmentLiftTime, onFragmentLiftTimeComplate);
			}
			mAllLiveSubFragmentVector.push(fragment);
		}

		//=================================
		//== Private Function
		//=================================

		private function onFragmentLiftTimeComplate(_fragment:CEGhostShadowSpriteFragment):void
		{
			removeFragmenFromLiveVector(_fragment);
			_fragment.recycle();
			mAllRecycleSubFragmentVector.push(_fragment);
		}

		private function removeFragmenFromLiveVector(_fragment:CEGhostShadowSpriteFragment):void
		{
			var index:int=mAllLiveSubFragmentVector.indexOf(_fragment);
			if (index >= 0)
			{
				mAllLiveSubFragmentVector.splice(index, 1);
			}
		}


	}
}
